iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 23
1
Modern Web

美麗的邂逅-與安室....伊春系列 第 23

競合二: 前端 (Link/Angular)

  • 分享至 

  • xImage
  •  
泰山不讓土壤,故能成其大;河海不擇細流,故能就其深。
  • GET (from HTML)
  • POST (from HTML)
  • CUSTOM_ELEMENTS_SCHEMA / NO_ERRORS_SCHEMA

接著介紹 Angular 的程式,這包含有許多模組。因為和 Spring Boot 侷限在 local host, 因此不用stackblitz. 如果讀者想要測試編碼,歡迎索取,在本例中產生的模組如下:

ng new angularclient --routing
ng g class user
ng g service user-service
ng g c user-form
ng g c user-list
其中 g=generate, c=component。

src/app/app.component.html

<div class="container">
  <div class="row">
    <div class="col-md-12">
      <div class="card bg-dark my-5">
        <div class="card-body">
          <h2 class="card-title text-center text-white py-3">{{ title }}</h2>
          <h4 class="card-title text-center text-white py-3">{{ author }}</h4>
          <ul class="text-center list-inline py-3">
            <li class="list-inline-item"><a routerLink="/users" class="btn btn-info">List Users</a></li>
            <li class="list-inline-item"><a routerLink="/adduser" class="btn btn-info">Add User</a></li>
          </ul>
        </div>
      </div>
      <router-outlet></router-outlet>
    </div>
  </div>
</div>

src/app/app.component.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Angular-Spring Boot-Demo';
  author = 'by Faust, 2019,9,28';
}

src/app/user-form.component.html

<div class="card my-5">
  <div class="card-body">
    <form (ngSubmit)="onSubmit()" #userForm="ngForm">
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" [(ngModel)]="user.name"
          class="form-control" id="name" name="name" placeholder="Enter your name"
          required #name="ngModel">
      </div>
      <div [hidden]="!name.pristine" class="alert alert-danger">Name is required</div>
      <div class="form-group">
        <label for="email">Email</label>
        <input type="text" [(ngModel)]="user.email"
          class="form-control" id="email" name="email" placeholder="Enter your email address"
          required #email="ngModel">
        <div [hidden]="!email.pristine" class="alert alert-danger">Email is required</div>
      </div>
      <button type="submit" [disabled]="!userForm.form.valid" class="btn btn-info">Submit</button>
    </form>
  </div>
</div>

[(ngModel)] 是作資料庫綁定,[hidden]是特定狀況下不顯示,!name.pristine 表明只有在 name 沒有值時再顯示,[hidden]=”!email.pristine”也是相同的意思。在 [disabled]=”!userForm.form.valid” 定義在submit 時會檢視是否有效。另外,第一行也是關鍵:

<form (ngSubmit)="onSubmit()" #userForm="ngForm">

src/app/user-form.component.ts (import 的編碼都省略了)

@Component({
  selector: 'app-user-form',
  templateUrl: './user-form.component.html',
  styleUrls: ['./user-form.component.css']
})
export class UserFormComponent {
  user: User;
  constructor(private route: ActivatedRoute, private router: Router, private userService: UserService) {
    this.user = new User();
  }
  onSubmit() {
    this.userService.save(this.user).subscribe(result => this.gotoUserList());
  }
  gotoUserList() {
    this.router.navigate(['/users']);
  }
}

留意到 onSubmit() 呼叫 save() (定義在 user-service.service.ts 中)。
src/app/app.module.ts

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ],
  schemas:      [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class AppModule { }

注意,因為在 app.component.html 中,有使用到標簽 <router_outlent>,這是未定義的標簽,因此會顯示錯誤,可以留意上面編碼中增加兩行,告知系統,就不會有錯誤。

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
...
schemas:      [ CUSTOM_ELEMENTS_SCHEMA ]

其中 CUSTOM_ELEMENTS_SCHEMA,亦可用 NO_ERRORS_SCHEMA 取代,新增記錄全部呼叫的流程依序條列下來,我們可以順著看呼收的過程:

app-component.component.html 
-> (routerLink="/users") -> app-routing.module.ts: { path: 'users' ... }
-> user-form.component.html (type=”submit”) -> user-form.comonent.ts: onSubmit()
-> this.userService.save(this.user) 
-> user-service.service.ts: save(user: User)
-> this.http.post<User>(this.usersUrl, user);
==> call spring boot (back end)  

另外,留意到 .subscribe( ), 這個指令還有許多變化。代表在結束(result) 執行 gotoUserList() 也就是列出所有的記錄。

src/app/model/User/User.ts

export class User {
id: string;
name: string;
email: string;
}

src/app/user-list/user-list.component.html

上一篇
競合一: 後端 (Link/Spring Boot)
下一篇
競合三: 溝通 (Link/HTTP)
系列文
美麗的邂逅-與安室....伊春30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言